
package futbol.tacticas.concursantes.drakkar;


import futbol.tacticas.*;
import futbol.tacticas.concursantes.Tactica;

import java.util.Vector;
import java.awt.Color;
import java.awt.Point;







/*
 * @author drakkar
 */
public class TacticaAsdf implements Tactica {
   
    private final static String NOMBRE = "Asdf";
    private final static Color COLOR1 = Color.LIGHT_GRAY;
    private final static Color COLOR2 = Color.LIGHT_GRAY;
    private final static Color COLOR3 = Color.DARK_GRAY;
    
    private final static int[] FUERZAS = {6, 6,6,6,6, 5,5,5,5,5,5};
    
    private Info info = new Info(FUERZAS);
    
    private int[][] posAtaqIni = { 
        {-150,   0},
        { -80,   0},
        { -30,   0},
        {   0, -60},
        {   0, +60},
        {   0, -60},
        {   0, +60},
        { -60, -60},
        { -60, +60},
        {   0, -60},
        {   0, +60},
    };
    
    private int[][] posAtaqFin = { 
        {-158,   0},
        { -95,   0},
        { -30,   0},
        { +35,   0},
        {+100,   0},
        {   2, -60},
        {   2, +60},
        { -63, -60},
        { -63, +60},
        { +68, -60},
        { +68, +60},
    };
    

    
    
    public TacticaAsdf(){
    }
    

    public Color getColor1() {
        return COLOR1;
    }

    public Color getColor2() {
        return COLOR2;
    }

    public Color getColorNumero() {
        return COLOR3;
    }

    public String getNombre() {
        return NOMBRE;
    }
    
    public int getXInicial(int n) {
        return 160 + 2*posAtaqIni[n][0];
    }

    public int getYInicial(int n) {
        return posAtaqIni[n][1];
    }

    public int getFuerza(int n) {
        return FUERZAS[n];
    }


    
    public Vector<Comando> getComandos(SituacionJugadores sj) {
        Accion acc = new Accion(info);
        Vector<Comando> com = new Vector();

        
        for(int n = 0; n < 11; n++) {
            com.add( new ComandoIrA(n, posAtaqFin[n][0], posAtaqFin[n][1]) );
        }
        
        
        try {
            info.calculos(sj);
        }
        catch(Exception e) {
            System.err.println("*ERROR*: info.calculos(sj);");
            e.printStackTrace();
        }
            
        try {
            acc.reset( 0); jugador00(acc); acc.addToCommandVector(com);
            acc.reset( 1); jugador01(acc); acc.addToCommandVector(com);
            acc.reset( 2); jugador02(acc); acc.addToCommandVector(com);
            acc.reset( 3); jugador03(acc); acc.addToCommandVector(com);
            acc.reset( 4); jugador04(acc); acc.addToCommandVector(com);
            acc.reset( 5); jugador05(acc); acc.addToCommandVector(com);
            acc.reset( 6); jugador06(acc); acc.addToCommandVector(com);
            acc.reset( 7); jugador07(acc); acc.addToCommandVector(com);
            acc.reset( 8); jugador08(acc); acc.addToCommandVector(com);
            acc.reset( 9); jugador09(acc); acc.addToCommandVector(com);
            acc.reset(10); jugador10(acc); acc.addToCommandVector(com);
        }
        catch(Exception e) {
//          System.err.println("*ERROR*: acc.reset(n); jugador??(acc); addAccion(com, acc);");
//          e.printStackTrace();
        }
        

        if( info.getBola().getQ() > 30 ) {
            int d = info.getGoles(0) - info.getGoles(1);
            long g = info.getDesempate(99999);
            if(  d < 0  ||  ( d == 0 && g < 100 )  ) {
                int n = sj.getInfoMasCercano(sj.getMisJugadores(), sj.getBola(), new int[] {0,1,2,3,4}, false)[0];
                com.add( new ComandoIrA(n, sj.getBola().x, sj.getBola().y) );
            }
        }
        
        return com;
    }
    
    
    
    private void jugador00(Accion acc) {
        Info.Jugador yo = info.getJugador(acc.n);
        int f = info.getFrameGolpeBola(yo);
        if(f == 0) {
            int g = info.getFramesLibre(info.getBola().getX(), info.getBola().getY(), 4);
            if(g > 1 && ( (info.getBola().getX() > -155) || info.getJugador(4).getX() < posAtaqFin[4][0]-4*15) ) {
                acc.mover(info.getBola().getX(), info.getBola().getY());
                acc.golpeV3(-155, posAtaqFin[acc.n][1]);
            }
            else {
                acc.mover(info.getBola().getX(), info.getBola().getY());
                acc.golpeVmax(info.getJugador(acc.n+1).getX(), info.getJugador(acc.n+1).getY());
            }
        }        
        else {
            double d = info.distancia(yo, info.getBola());
            if(f <= 5 || d < 5*yo.getV())
                acc.mover(info.getBola().getX(f), info.getBola().getY(f));
            else
                acc.mover(posAtaqFin[0][0], (posAtaqFin[0][1]*0.6+info.getBola().getY()*0.4));
            acc.golpeVmax(info.getJugador(acc.n+1).getX(), info.getJugador(acc.n+1).getY());
        }
    }

    
    
    private void jugador01(Accion acc) {
        Info.Jugador yo = info.getJugador(acc.n);
        int f = info.getFrameGolpeBola(yo);
        if(f < 3 && info.getGolTicks() < 12) {
            acc.mover(info.getBola().getX(f), info.getBola().getY(f));
            acc.golpeV12(-160, 0);
        }
        else if(f == 0) {
            int g = info.getFramesLibre(info.getBola().getX(), info.getBola().getY(), 4);
            if(g > 1 && info.getBola().getX() < posAtaqFin[acc.n][0]+6) {
                acc.mover(info.getBola().getX()+0, info.getBola().getY());
                acc.golpeV3(posAtaqFin[acc.n][0]+15, posAtaqFin[acc.n][1]);
            }
            else {
                acc.mover(info.getBola().getX(), info.getBola().getY());
                acc.golpeVmax(info.getJugador(acc.n+1).getX(), info.getJugador(acc.n+1).getY());
            }
        }
        else {
            double d = info.distancia(yo, info.getBola());
            if(f <= 3 || d < 3*yo.getV())
                acc.mover(info.getBola().getX(f), info.getBola().getY(f));
            else
                acc.mover(info.getJugador(acc.n-1).getX()+66, (posAtaqFin[acc.n][1]+info.getJugador(acc.n-1).getY())*0.5);
            acc.golpeVmax(info.getJugador(acc.n+1).getX(), info.getJugador(acc.n+1).getY());
        }
    }

    
    
    private void jugador02(Accion acc) {
        Info.Jugador yo = info.getJugador(acc.n);
        int f = info.getFrameGolpeBola(yo);
        if(f < 3 && info.getGolTicks() < 6) {
            acc.mover(info.getBola().getX(f), info.getBola().getY(f));
            acc.golpeV12(-160, 0);
        }
        else if(f == 0) {
            int g = info.getFramesLibre(info.getBola().getX(), info.getBola().getY(), 4);
            if(g > 1 && info.getBola().getX() < posAtaqFin[acc.n][0]+6) {
                acc.mover(info.getBola().getX()+0, info.getBola().getY());
                acc.golpeV3(posAtaqFin[acc.n][0]+15, posAtaqFin[acc.n][1]);
            }
            else {
                acc.mover(info.getBola().getX(), info.getBola().getY());
                acc.golpeVmax(info.getJugador(acc.n+1).getX(), info.getJugador(acc.n+1).getY());
            }
        }
        else {
            double d = info.distancia(yo, info.getBola());
            if(f <= 3 || d < 3*yo.getV())
                acc.mover(info.getBola().getX(f), info.getBola().getY(f));
            else
                acc.mover(info.getJugador(acc.n-1).getX()+66, (posAtaqFin[acc.n][1]+info.getJugador(acc.n-1).getY())*0.5);
            acc.golpeVmax(info.getJugador(acc.n+1).getX(), info.getJugador(acc.n+1).getY());
        }
    }

    
    
    private void jugador03(Accion acc) {
        Info.Jugador yo = info.getJugador(acc.n);
        int f = info.getFrameGolpeBola(yo);
        if(f == 0) {
            int g = info.getFramesLibre(info.getBola().getX(), info.getBola().getY(), 4);
            if(g > 1 && info.getBola().getX() < posAtaqFin[acc.n][0]+6) {
                acc.mover(info.getBola().getX()+0, info.getBola().getY());
                acc.golpeV3(posAtaqFin[acc.n][0]+15, posAtaqFin[acc.n][1]);
            }
            else {
                acc.mover(info.getBola().getX(), info.getBola().getY());
                acc.golpeVmax(info.getJugador(acc.n+1).getX(), info.getJugador(acc.n+1).getY());
            }
        }
        else {
            double d = info.distancia(yo, info.getBola());
            if(f <= 3 || d < 3*yo.getV())
                acc.mover(info.getBola().getX(f), info.getBola().getY(f));
            else
                acc.mover(info.getJugador(acc.n-1).getX()+66, (posAtaqFin[acc.n][1]+info.getJugador(acc.n-1).getY())*0.5);
            acc.golpeVmax(info.getJugador(acc.n+1).getX(), info.getJugador(acc.n+1).getY());
        }
    }

    
    
    private void jugador04(Accion acc) {
        Info.Jugador yo = info.getJugador(acc.n);
        int f = info.getFrameGolpeBola(yo);
        if(f == 0) {
            int g = info.getFramesLibre(info.getBola().getX(), info.getBola().getY(), 4);
            if(g > 1 && info.getBola().getX() < posAtaqFin[acc.n][0]+6) {
                acc.mover(info.getBola().getX()+0, info.getBola().getY());
                acc.golpeV3(posAtaqFin[acc.n][0]+15, posAtaqFin[acc.n][1]);
            }
            else {
                acc.mover(info.getBola().getX(), info.getBola().getY());
                acc.golpeVmax(161, 0);
            }
        }
        else {
            double d = info.distancia(yo, info.getBola());
            if(f <= 3 || d < 3*yo.getV())
                acc.mover(info.getBola().getX(f), info.getBola().getY(f));
            else
                acc.mover(info.getJugador(acc.n-1).getX()+66, (posAtaqFin[acc.n][1]+info.getJugador(acc.n-1).getY())*0.5);
            acc.golpeVmax(161, 0);
        }
    }
    
    

    private void jugador05(Accion acc) {
        jugadorLateral(acc);
    }

    
    
    private void jugador06(Accion acc) {
        jugadorLateral(acc);
    }

    
    
    private void jugador07(Accion acc) {
        jugadorLateral(acc);
        if(info.getGolTicks() < 20)
            acc.golpeV12(-155, 0);
    }

    
    
    private void jugador08(Accion acc) {
        jugadorLateral(acc);
        if(info.getGolTicks() < 20)
            acc.golpeV12(-155, 0);
    }

    
    
    private void jugador09(Accion acc) {
        jugadorLateral(acc);
    }

    
    
    private void jugador10(Accion acc) {
        if(info.getGolTicks() < 2) {
            acc.golpeVmax(-160, 0);
            acc.mover(posAtaqFin[acc.n][0], posAtaqFin[acc.n][1]);
        }
        else {
            jugadorLateral(acc);
        }
    }
    
    
    
    
    
    private void jugadorLateral(Accion acc) {
        Info.Jugador yo = info.getJugador(acc.n);
        acc.mover(posAtaqFin[acc.n][0], posAtaqFin[acc.n][1]);
        acc.golpeVmax(info.getJugador(3).getX(), info.getJugador(3).getY());
        Info.Jugador quien = info.quienTieneBalon();
        if( info.puedeGolpear(yo) ) {
            if( info.esElMismo(yo, quien) ) {
                int f = info.getFramesLibre(info.getBola().getX(), info.getBola().getY(), 4);
                if(f > 1) {
                    // puede perder el tiempo...
                    jugadorLateralAccion(acc, false);
                }
                else {
                    // golpe desesperado -> mejor direccion
                    jugadorLateralAccion(acc, true);
                }
            }
            else if(quien != null && quien.getE() == 1) {
                // la tiene el malo !!, golpe obligatorio -> fuerza minimo 15 -> mejor direccion
                jugadorLateralAccion(acc, true);
            }
            else if(quien != null && quien.getE() == 0) {
                // la tiene alguien de mi equipo... ayudarle ?
                acc.mover(posAtaqFin[acc.n][0], posAtaqFin[acc.n][1]); // no, XD
            }
        }
        else {
            if(quien == null || quien.getE() == 1) {
                Point p = new Point();
                double d = info.getPuntoBolaCercano(yo, p);
                if(d < 60) acc.mover(p);
            }
        }
    }
    
    
      
    
    private void jugadorLateralAccion(Accion acc, boolean urgencia) {
        int[] heur = new int[] {  
            /* pasar a otro jugador  */  20,  25, 30, 35, 40,  20, 20,  20, 20,  25, 25,
            /* aleatorio mejor f=max */  -50,-50,-50,-50,-50,-50,-50,-50,
            /* aleatorio mejor f=3   */  10,10,10,10,10,10,10,10,
            /* aleatorio mejor f=6   */  20,20,20,20,20,20,20,20
            /* aleatorio mejor f=9   */  //2,2,2,2,2,2,2,2,
            /* aleatorio mejor f=12  */  //3,3,3,3,3,3,3,3,
            /* aleatorio mejor f=15  */  //4,4,4,4,4,4,4,4,
            /* aleatorio mejor f=18  */  //5,5,5,5,5,5,5,5,
            /* aleatorio mejor f=21  */  //6,6,6,6,6,6,6,6
        };
        
        double a = 0, x = 0, y = 0;
        int m = 0, num = heur.length;
        if(urgencia && num > 11+8) num = 11+8;
        jugadorLateralAccionHeurs(acc.n, num, heur);
        for(int n = 1; n < num; n++) {
            if(heur[n] > heur[m]) m = n;
        }        
        acc.mover(info.getBola().getX(), info.getBola().getY());
        if(m < 11) {
            acc.golpeVmax(info.getJugador(m).getX(), info.getJugador(m).getY());
        }
        else {
            a = ((m-11)%8)*0.7853981;
            x = info.getBola().getX() + 200*Math.cos(a);
            y = info.getBola().getY() + 200*Math.sin(a);
            if      (m < 11+1*8)  acc.golpeVmax(x, y);
            else if (m < 11+2*8)  acc.golpeV3  (x, y);
            else if (m < 11+3*8)  acc.golpeV6  (x, y);
            else if (m < 11+4*8)  acc.golpeV9  (x, y);
            else if (m < 11+5*8)  acc.golpeV12 (x, y);
            else if (m < 11+6*8)  acc.golpeV15 (x, y);
            else if (m < 11+7*8)  acc.golpeV18 (x, y);
            else if (m < 11+8*8)  acc.golpeV21 (x, y);
            else                  acc.golpeVmax(x, y);
        }
    }

    private void jugadorLateralAccionHeurs(int jn, int num, int[] heur) {
        Info.Jugador yo = info.getJugador(jn);
        if( !info.puedeGolpear(yo) ) return;
        Info.Bola bola = info.getCopyBola();
        int f = 0, d, r, v, g, gMin = 1<<30;
        double a = 0, x = 0, y = 0;
        if(num < heur.length) num = heur.length;
        Point p = new Point();
        for(int n = 0; n < num; n++) {
            info.copyBola(bola, info.getBola());
            if(n < 11) {
                x = info.getJugador(n).getX();
                y = info.getJugador(n).getY();
                info.simularGolpeBolaSinError(yo, x, y, bola, 99);
            }
            else {
                if      (n < 11+1*8) f = 99;
                else if (n < 11+2*8) f =  3;
                else if (n < 11+3*8) f =  6;
                else if (n < 11+4*8) f =  9;
                else if (n < 11+5*8) f = 12;
                else if (n < 11+6*8) f = 15;
                else if (n < 11+7*8) f = 18;
                else if (n < 11+8*8) f = 21;
                a = ((n-11)%8)*0.7853981;
                x = bola.getX() + 200*Math.cos(a);
                y = bola.getY() + 200*Math.sin(a);
                info.simularGolpeBolaSinError(yo, x, y, bola, f);
            }
            d = (int)info.distancia(x, y, bola);
            v = bola.getV();
            for(f = 0; f <= v; f++) {
                if(bola.getDist(f) >= d) break;
                r = (int)bola.getErr(f);
                r = 1 + ( r < 0 ? -r : r );
                g = info.getFramesLibre(bola.getX(f), bola.getY(f), r, f);
                if(g <= 0) {
                    heur[n] = -99999;
                    break;
                }
            }
            if(n < 11) {
                heur[n] *= 10;
            }
            else {
                heur[n] += ( bola.getX(f) - bola.getX() ) / 2;
                if(bola.getY(f)*bola.getY(f) > 40*40) heur[n] -= 10;
                if(bola.getX(f) < -140) heur[n] -= 30;
                if(bola.getX(f) > +145) heur[n] -= 30;
                if(bola.getDist(f) > 66) heur[n] -= 10;
                if(bola.getDist(f) > 75) heur[n] -= 10;
                if(bola.getDist(f) > 80) heur[n] -= 10;
            }
        }
    }
    
    
}

